﻿using System.Collections.Generic;
using Socium.Domain.Collections;
using Socium.Domain.Documents;
using Socium.Presentation;

namespace Socium.Documents.Sociomatrices {
	class SociomatrixViewModel : PageViewModel {
		//readonly Document _document;
		//readonly Sociomatrix _sociomatrix;

		readonly ICollection<CellViewModel> _cells = new LinkedList<CellViewModel>();

		public SociomatrixViewModel(Document document, Sociomatrix sociomatrix) :base(sociomatrix.Name) {
			//_document = document;
			//_sociomatrix = sociomatrix;

			DisplayName = sociomatrix.Name;

			var persons = sociomatrix.Persons.ToArray();
			//var card_persons = card.GetPersons();

            Cells.Add(new StubCellViewModel {Column = 0, Row = 0});

		    Cells.AddRange(persons.MapIndexedLazy(CreateColumnViewModel));
		    Cells.AddRange(persons.MapIndexedLazy(CreateRowViewModel));

			var criterias_dictionary = new Dictionary<RelationGroup, RelationGroupViewModel>();
			criterias_dictionary.AddRange(document.Criterias.MapLazy(CreateCriteriaPair));

			var length = persons.Length;
			for (var i = 0; i < length; i++) {
				var elector = persons[i];
				for (var j = 0; j < length; j++) {
					var elected = persons[j];
					var elections = document.Relations.FilterLazy(relation => RelationFilter(elected, elector, relation));
					var criteria_view_models = elections.MapLazy(relation => criterias_dictionary[relation.RelationGroup]);

					var name = string.Format("{0} - {1}", elector, elected);
					var election_view_model = new ElectionViewModel(name, elector, elected) {
						Row = i + 1,
						Column = j + 1
					};
					election_view_model.Elections.AddRange(criteria_view_models);
					_cells.Add(election_view_model);
				}
			}

			Count = length + 1;
		}

		public int Count { get; private set; }

		static KeyValuePair<RelationGroup, RelationGroupViewModel> CreateCriteriaPair(RelationGroup relation_group) {
			return CreateCriteriaViewModel(relation_group).MakePair(relation_group);
		}

		static RelationGroupViewModel CreateCriteriaViewModel(RelationGroup relation_group) {
			return new RelationGroupViewModel(relation_group);
		}

		static bool RelationFilter(Person elected, Person elector, Relation relation) {
			return relation.From == elector && relation.To == elected;
		}

		public ICollection<CellViewModel> Cells {
			get { return _cells; }
		}

		static RowlViewModel CreateRowViewModel(Person person, int index) {
			return new RowlViewModel(person) {
				Row = index + 1,
				Column = 0
			};
		}

		static ColumnViewModel CreateColumnViewModel(Person person, int index) {
			return new ColumnViewModel(person) {
			    Row = 0,
			    Column = index + 1,
			};
		}

		
	}
}
